home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / batchut / desetp12.zip / SETPATH.C < prev    next >
C/C++ Source or Header  |  1991-09-07  |  8KB  |  306 lines

  1. /**
  2.  **
  3.  ** SETPATH -- A utility for showing or setting the DOS environment path string
  4.  **
  5.  ** Version 1.2  09/08/91  (for Microsoft C Version 5.1)
  6.  ** Copyright (c) D. E. Ekman 1990, 1991.  All rights reserved.
  7.  **
  8.  ** SETPATH either prints or sets the current PATH environment variable.  When
  9.  ** setting the PATH variable, SETPATH expects a PATH string in the form 
  10.  ** required by DOS, or the name of a file containing the wanted PATH string.
  11.  ** In either case, SETPATH replaces any existing PATH environment variable with
  12.  ** the new string.  The new string need not be the same length as the current
  13.  ** string, but if it is longer, there must be enough available environment
  14.  ** space to accommodate it.  In particular, the string may be longer than the
  15.  ** 128-byte limit imposed by the DOS command line buffer, but to use this
  16.  ** feature, the PATH string must come from a file.
  17.  **
  18.  ** Usage:
  19.  **
  20.  **  SETPATH
  21.  **
  22.  **  SETPATH path_string
  23.  **
  24.  **  SETPATH -f[d:\path]filename or SETPATH -F[d:\path]filename or
  25.  **  SETPATH /f[d:\path]filename or SETPATH /F[d:\path]filename
  26.  **
  27.  ** where:
  28.  **
  29.  **   path_string is the new PATH environment variable string in the same
  30.  **   form required by the DOS PATH command.  (Do not include "PATH=".)
  31.  **
  32.  **   filename is the name of a file containing the new PATH string.  The drive
  33.  **   and path qualifiers are optional.  No space is permitted between the
  34.  **   switch (-f, -F, /f, or /F) and its argument.  The file content must have
  35.  **   the form:
  36.  **
  37.  **      PATH=any_wanted_text_string
  38.  **
  39.  **   The word PATH may be any combination of upper and lower case letters.
  40.  **   This word and the following equals sign are required to help prevent
  41.  **   using the wrong file, and must be the first five characters in the file
  42.  **   except for spaces and control characters such as tabs and newlines.
  43.  **   Before placing the file content in the environment, SETPATH changes any
  44.  **   lower case characters in the word PATH to upper case and squeezes out all
  45.  **   blanks and all control characters.  (SETPATH defines a control character
  46.  **   as any character in the range 0x00-0x1f and the character 0x7f.)  If you
  47.  **   do use newlines to separate the elements of your path string, do not
  48.  **   forget the required semicolons; SETPATH will NOT add them automatically.
  49.  **
  50.  ** An error message is issued, and the current PATH string remains undisturbed,
  51.  ** on any of the following conditions:
  52.  **
  53.  **   More than one argument
  54.  **
  55.  **   Specified file cannot be opened
  56.  **
  57.  **   Failure in fseek searching for end of file
  58.  **
  59.  **   Failure in ftell finding file length
  60.  **
  61.  **   Memory allocation failure creating buffer for new PATH contents
  62.  **
  63.  **   Specified file does not begin with "PATH="
  64.  **
  65.  **   Not enough environment space for new path
  66.  **
  67.  ** A successful completion message is issued when SETPATH inserts the new
  68.  ** PATH string into the environment.
  69.  **
  70.  **/
  71.  
  72. #include <stdio.h>
  73. #include <string.h>
  74. #include <stdlib.h>
  75. #include <ctype.h>
  76.  
  77. main(argc,argv)
  78. int argc;
  79. char *argv[];
  80. {
  81.     int count, seekresult, pathlength, available, olength, ch;
  82.     unsigned int envseg, envsize, envinuse;
  83.     long int filelength;
  84.     char *filebuff;
  85.     char far *ptr, far *pathptr, far *endptr;
  86.     FILE *ip;
  87.     int numread = 0;
  88.     
  89.     printf("\nThe Ekman Utility SETPATH, V1.2\n");
  90.     printf("Copyright (c) D. E. Ekman 1990, 1991.  All rights reserved.\n");
  91.     
  92.     if(argc > 2)
  93.     {
  94.     printf("\nSetpath:  Too many arguments\007\n");
  95.     return (1);
  96.     }
  97.     if(argc > 1)
  98.     {
  99.     if(strnicmp(argv[1],"-f",2) &&
  100.        strnicmp(argv[1],"/f",2))
  101.         {
  102.         if((filebuff = (char *)malloc((strlen(argv[1])+8)*
  103.           sizeof(char))) == NULL)
  104.         {
  105.         printf("\nSetpath:  Failure allocating new PATH buffer\007\n");
  106.         return (5);
  107.         }
  108.         else
  109.         {
  110.         sprintf(filebuff,"PATH=%s",argv[1]);
  111.         numread = strlen(filebuff);
  112.         }
  113.         }
  114.     else
  115.         {
  116.         if(!(ip = fopen(&argv[1][2],"r")))
  117.         {
  118.         printf("\nSetpath:  Can't open path file %s\007\n",&argv[1][2]);
  119.         return (2);
  120.         }
  121.         if(seekresult = fseek(ip, 0L, SEEK_END))
  122.         {
  123.         printf("\nSetpath:  Failure seeking end of %s\007\n",
  124.                &argv[1][2]);
  125.         return (3);
  126.         }
  127.         if((filelength = ftell(ip)) < 0)
  128.         {
  129.         printf("\nSetpath:  Failure in ftell with %s\007\n",
  130.                &argv[1][2]);
  131.         return (4);
  132.         }
  133.         rewind(ip);
  134.         if ((filebuff = (char *)malloc((filelength+2)*sizeof(char)))
  135.         == NULL)
  136.         {
  137.         printf("\nSetpath:  Failure allocating new PATH buffer\007\n");
  138.         return (5);
  139.         }
  140.         ch = fgetc(ip);
  141.         for(numread = 0; (numread < filelength) && (!feof(ip)) ;)
  142.         {
  143.         if(isascii(ch) && (!iscntrl(ch)) && ch != ' ')
  144.             {
  145.             if(numread < 4)
  146.             ch = toupper(ch);
  147.             *(filebuff + numread++) = ch;
  148.             }
  149.         ch = fgetc(ip);
  150.         }
  151.         *(filebuff + numread++) = '\0';
  152.         if(strncmp(filebuff, "PATH=", 5))
  153.         {
  154.         printf("\nSetpath:  Path file %s must begin with %s\007\n",
  155.                &argv[1][2],"PATH=");
  156.         return (6);
  157.         }
  158.         }
  159.     }
  160.     getsysenv(&envseg, &envsize, &envinuse);
  161.     ptr = (char far *) ((long) envseg << 16);
  162.     pathptr = NULL;
  163.     while(*ptr != '\0')
  164.     {
  165.     if(*ptr == 'P' && *(ptr+1) == 'A' && *(ptr+2) == 'T' &&
  166.         *(ptr+3) == 'H' && *(ptr+4) == '=')
  167.         {
  168.         pathptr = ptr;
  169.         break;
  170.         }
  171.     while(*ptr++ != '\0')
  172.         ;
  173.     }
  174.     if(!numread)
  175.     {
  176.     printf("\n");
  177.     while(*pathptr)
  178.         putch(*pathptr++);
  179.     puts("");
  180.     return (0);
  181.     }
  182.     pathlength = 0;
  183.     if(pathptr != NULL)
  184.     {
  185.     while(*(pathptr + pathlength++) != '\0')
  186.         ;
  187.     }
  188.     available = envsize - envinuse + pathlength;
  189.     if(numread > available)
  190.     {
  191.     printf("\nSetpath:  Not enough environment space for new path\007\n");
  192.     return (7);
  193.     }
  194.     ptr = (char far *) ((long) envseg << 16);
  195.     olength = envinuse - (pathptr - ptr + pathlength);
  196.     endptr = ptr + envinuse -1;
  197.     if(pathptr != NULL)
  198.     {
  199.     if(numread == pathlength)
  200.         {
  201.         while(*pathptr++ = *filebuff++)
  202.         ;
  203.         }
  204.     if(numread < pathlength)
  205.         {
  206.         ptr = pathptr + pathlength;
  207.         while(*pathptr++ = *filebuff++)
  208.         ;
  209.         for(count = 0; count < olength; count++)
  210.         *pathptr++ = *ptr++;
  211.         }
  212.     if(numread > pathlength)
  213.         {
  214.         ptr = endptr + numread - pathlength;
  215.         for(count = 0; count < olength; count++)
  216.         *ptr-- = *endptr--;
  217.         while(*pathptr++ = *filebuff++)
  218.         ;
  219.         }
  220.     }
  221.     else
  222.     {
  223.     while(*ptr != '\0')
  224.         {
  225.         if((*ptr != 'C' || *(ptr+1) != 'O' || *(ptr+2) != 'M' ||
  226.         *(ptr+3) != 'S' || *(ptr+4) != 'P' || *(ptr+5) != 'E' ||
  227.         *(ptr+6) != 'C' || *(ptr+7) != '=') &&
  228.         (*ptr != 'P' || *(ptr+1) != 'R' || *(ptr+2) != 'O' ||
  229.         *(ptr+3) != 'M' || *(ptr+4) != 'P' || *(ptr+5) != 'T' ||
  230.         *(ptr+6) != '='))
  231.         {
  232.         pathptr = ptr;
  233.         break;
  234.         }
  235.         while(*ptr++ != '\0')
  236.         ;
  237.         }
  238.     ptr = endptr + numread;
  239.     for(count = 0; count < olength; count++)
  240.         *ptr-- = *endptr--;
  241.     while(*pathptr++ = *filebuff++)
  242.         ;
  243.     }
  244.     printf("\n New PATH string successfully placed in environment.\n");
  245.     return(0);
  246. }
  247.  
  248. getsysenv(envseg, envsize, envinuse)
  249. unsigned *envseg, *envsize, *envinuse;
  250. {
  251.     unsigned getdospsp(), computeenvinuse(), dospsp, temp;
  252.     unsigned far *ptr;
  253.     
  254.     dospsp = getdospsp();
  255.     ptr = (unsigned far *) (((long) dospsp << 16) | 0x2c);
  256.     temp = *ptr;
  257.     if((temp != 0) && (_osmajor != 3 || _osminor <= 19 || _osminor >= 30))
  258.     {
  259.     *envseg = temp;
  260.     }
  261.     else
  262.     {
  263.     ptr = (unsigned far *) (((long) (dospsp-1) << 16) | 3);
  264.     *envseg = dospsp + (*ptr) + 1;
  265.     }
  266.     ptr = (unsigned far *) (((long) ((*envseg)-1) << 16) | 3);
  267.     *envsize = 16*(*ptr);
  268.     *envinuse = computeenvinuse(*envsize, *envseg);
  269.     return(0);
  270. }
  271.  
  272. unsigned getdospsp()
  273. {
  274.     unsigned temp,temp1;
  275.     unsigned far *ptr;
  276.  
  277.     ptr = (unsigned far *) (((long) _psp << 16) | 0x16);
  278.     temp = *ptr;        
  279.     while(1)
  280.     {
  281.     ptr = (unsigned far *) (((long) temp << 16) | 0x16);
  282.     temp1 = *ptr;
  283.     if((!temp1) || (temp1 == temp))
  284.         return(temp);
  285.     else
  286.         temp = temp1;
  287.     }
  288. }
  289.  
  290. unsigned computeenvinuse(envsize, envseg)
  291. unsigned envsize, envseg;
  292. {
  293.     unsigned j;